/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.amse.grigory.dchess.io;

import org.amse.grigory.dchess.kernel.*;
import java.io.*;
import java.util.*;
import org.amse.grigory.dchess.rules.*;

/**
 *
 * @author grigory
 */
@Deprecated
public class TextReader implements IReader {
    // Constants
    private static final int BUFFER_SIZE = 65536;
    // Fields
    private String myFileName = "";
    private FileReader myFile;
    private String myText = "";
    private ArrayList<Figure> myTemplate;
    // Constructors

    /**
     * Assosiates Creader with file
     * @param name name of file
     * @throws java.io.IOException
     */
    public TextReader(String name) {
        myFileName = name;
        myTemplate = new ArrayList<Figure>();
    }

    //Getters
    public String getFileName() {
        return myFileName;
    }   

    //Setters
    public void setFileName(String name) {
        myFileName = name;
    }
    

    //Methods
    public void close() throws IOException {
        myFile.close();
        myFileName = "";
        myText = "";
        myTemplate = new ArrayList<Figure>();
    }

    /**
     * Open file.
     * And check format.
     * @throws java.io.IOException
     */
    public void open() throws IOException {
        myFile = new FileReader(myFileName);
        StringBuilder builder = new StringBuilder();
        char[] temp = new char[BUFFER_SIZE];
        int c = 0;
        c = myFile.read(temp);
        int i = 0;
        boolean inText = false;//is symbol in text

        while (i < c) {
            if (temp[i] == '#') {
                while ((i < c) && (temp[i] != (char) 10)) {
                    ++i;
                }
            } else {
                boolean need = true;//if symbol is nessecary

                if (temp[i] == (char) 9) {
                    need = false;
                }
                if (temp[i] == ' ') {
                    need = false;
                }

                if (need) {
                    boolean sp = false;//if symbol is reserved

                    switch (temp[i]) {
                        case '{': {
                            sp = true;
                            break;
                        }
                        case '}': {
                            sp = true;
                            break;
                        }
                        case ',': {
                            sp = true;
                            break;
                        }
                        case '=': {
                            sp = true;
                            break;
                        }
                        default:
                            break;
                    }
                    if (!sp) {
                        builder.append(charCase(temp[i], inText));
                    } else {
                        builder.append(' ');
                        builder.append(charCase(temp[i], inText));
                        builder.append(' ');

                    }
                }
            }
            if (temp[i] == '"') {
                inText = (!inText);
            }
            ++i;
        }
        myText = builder.toString();

    }

    private static char charCase(char c, boolean b) {
        if (b) {
            return c;
        } else {
            return Character.toLowerCase(c);
        }

    }

    // Methods to create rules
    public Rules createRules() {
        int i;
        int j = 0;
        Rules rules=new BasicChessRules();
        // total number of braces
        int count = 0;
        char[] txt = myText.toCharArray();
        int length = txt.length;
        for (i = 0; i < length; ++i) {
            if (txt[i] == '{') {
                j++;
                count++;
            }
            if (txt[i] == '{') {
                j--;
                count++;
            }
            if (j < 0) {
                return null;
            }
        }
        if (j != 0) {
            return null;
        }

        int[] closebraces = new int[length];
        i = 0;
        int[] bracnum = new int[count];
        int curr = -1;
        while (i < length) {

            if (txt[i] == '{') {
                curr++;
                bracnum[curr] = i;
            }
            if (txt[i] == '}') {
                closebraces[i] = bracnum[curr];
                closebraces[bracnum[curr]] = i;
                curr--;
            }
            i++;
        }

        // Scanner to get information from text 
        Scanner parser = new Scanner(myText);
        String temp = "";
        int index = 0;
        while (parser.hasNext()) {
            index = next(index, temp, myText);
            temp = parser.next();
            if (temp.equals("name")) {
                index = next(index, temp, myText);
                temp = parser.next();
                if (!temp.equals("=")) {
                    return null;
                }
                index = next(index, temp, myText);
                temp = parser.next();
                if ((temp.charAt(0) == '"') &&
                        (temp.charAt(temp.length() - 1) == '"')) {
                    rules.setName(temp.substring(1, temp.length() - 1));
                }
            }
            if (temp.equals("desk")) {
                index = next(index, temp, myText);
                temp = parser.next();
                if (temp.equals("{")) {
                    temp = myText.substring(index + 1, closebraces[index]);
                    if (!rulesFromString(temp, index, closebraces, rules)) {
                        return null;
                    }
                    temp = "}";
                    int toindex = closebraces[index];
                    while (index < toindex) {
                        index = next(index, temp, myText);
                        temp = parser.next();
                    }
                } else {
                    return null;
                }
            }

            if (temp.equals("figures")) {
                index = next(index, temp, myText);
                temp = parser.next();
                if (temp.equals("{")) {
                    temp = myText.substring(index + 1, closebraces[index]);
                    if (!figuresFromString(temp, index, closebraces, rules)) {
                        return null;
                    }
                    temp = "}";
                    int toindex = closebraces[index];
                    while (index < toindex) {
                        index = next(index, temp, myText);
                        temp = parser.next();
                    }
                } else {
                    return null;
                }
            }
            if (temp.equals("position")) {
                index = next(index, temp, myText);
                temp = parser.next();
                if (temp.equals("{")) {
                    temp = myText.substring(index + 1, closebraces[index]);
                    if (!postionFromString(temp, index, closebraces, rules)) {
                        return null;
                    }
                    temp = "}";
                    int toindex = closebraces[index];
                    while (index < toindex) {
                        index = next(index, temp, myText);
                        temp = parser.next();
                    }
                } else {
                    return null;
                }
            }
        }



        return rules;
    }

    // Auxiliary methods
    private int next(int index, String pattern, String text) {
        int temp = index + pattern.length();
        while ((text.charAt(temp) == ' ') || (text.charAt(temp) == '\n')) {
            ++temp;
        }
        return temp;
    }

    private boolean rulesFromString(String text, int begin,
            int[] closebraces, Rules rules) {
        int index = 0;
        Scanner parser = new Scanner(text);
        String temp = "";
        while (parser.hasNext()) {
            index = next(index, temp, text);
            temp = parser.next();
            if (temp.equals("height")) {
                index = next(index, temp, text);
                temp = parser.next();
                if (!temp.equals("=")) {
                    return false;
                }
                index = next(index, temp, text);
                temp = parser.next();
                rules.setHeight(Integer.valueOf(temp).intValue());

            }
            if (temp.equals("width")) {
                index = next(index, temp, text);
                temp = parser.next();
                if (!temp.equals("=")) {
                    return false;
                }
                index = next(index, temp, text);
                temp = parser.next();
                rules.setWidth(Integer.valueOf(temp).intValue());
            }
            if (temp.equals("illegal")) {
                index = next(index, temp, text);
                temp = parser.next();
                if (!temp.equals(",")) {
                    return false;
                }
                next(index, temp, text);
                temp = parser.next();
                int x = Integer.valueOf(temp).intValue();
                index = next(index, temp, text);
                temp = parser.next();
                if (!temp.equals(",")) {
                    return false;
                }
                next(index, temp, text);
                temp = parser.next();
                int y = Integer.valueOf(temp).intValue();
                rules.addIllegalSquare(x - 1, y - 1);

            }
        }
        return true;
    }

    private boolean figuresFromString(String text, int begin,
            int[] closebraces, Rules rules) {
        int index = 0;
        Scanner parser = new Scanner(text);
        String temp = "";
        while (parser.hasNext()) {
            index = next(index, temp, text);
            temp = parser.next();
            if (temp.equals("newfigure")) {
                index = next(index, temp, text);
                temp = parser.next();
                if (temp.equals("{")) {
                    temp = myText.substring(index + begin + 2, closebraces[index + begin + 1]);
                    if (!figureFromString(temp, index + begin, closebraces, rules)) {
                        return false;
                    }
                    temp = "}";
                    int toindex = closebraces[index + begin + 1] - begin - 1;
                    while (index < toindex) {
                        index = next(index, temp, text);
                        temp = parser.next();
                    }
                } else {
                    return false;
                }

            }

        }
        return true;
    }

    private boolean figureFromString(String text, int begin,
            int[] closebraces, Rules rules) {
        Figure tmp = new Figure();
        Scanner parser = new Scanner(text);
        String temp = "";
        while (parser.hasNext()) {
            temp = parser.next();
            if (temp.equals("name")) {
                temp = parser.next();
                if (!temp.equals("=")) {
                    return false;
                }
                temp = parser.next();
                temp = temp.substring(1, temp.length() - 1);
                tmp.setName(temp);
            }
            if (temp.equals("move")) {
                temp = parser.next();
                if (!temp.equals("{")) {
                    return false;
                }
                temp = parser.next();
                if (temp.equals("to")) {
                    temp = parser.next();
                    temp = parser.next();
                    int x = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    temp = parser.next();
                    int y = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    tmp.addMove(x, y, '0');
                }
                if (temp.equals("vect")) {
                    temp = parser.next();
                    temp = parser.next();
                    int x = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    temp = parser.next();
                    int y = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    temp = parser.next();
                    char type;
                    if (temp.equals("a")) {
                        type = Moves.MOVE_SLIDE;
                    } else {
                        type = Moves.MOVE_FSLIDE;
                    }
                    temp = parser.next();
                    int tx = 0;
                    int ty = 0;
                    int length = Math.max(rules.getWidth(), rules.getHeight());
                    for (int i = 1; i < length; ++i) {
                        tx += x;
                        ty += y;
                        tmp.addMove(tx, ty, type);
                    }
                }
                temp = parser.next();
                temp = parser.next();
                temp = temp.substring(1, temp.length() - 1);
                if (temp.equals("slide")) {
                    tmp.setMoveType(tmp.getMovesCount() - 1, '0');
                }
                if (temp.equals("jump")) {
                    tmp.setMoveType(tmp.getMovesCount() - 1, '1');
                }
                if (temp.equals("fslide")) {
                    tmp.setMoveType(tmp.getMovesCount() - 1, '2');
                }
                if (temp.equals("fjump")) {
                    tmp.setMoveType(tmp.getMovesCount() - 1, '3');
                }
                temp = parser.next();
                if (!temp.equals("}")) {
                    return false;
                }
            }
            if (temp.equals("eat")) {
                temp = parser.next();
                if (!temp.equals("{")) {
                    return false;
                }
                temp = parser.next();
                if (temp.equals("to")) {
                    temp = parser.next();
                    temp = parser.next();
                    int x = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    temp = parser.next();
                    int y = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    tmp.addEat(x, y, '0');
                }
                if (temp.equals("vect")) {
                    temp = parser.next();
                    temp = parser.next();
                    int x = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    temp = parser.next();
                    int y = Integer.valueOf(temp).intValue();
                    temp = parser.next();
                    temp = parser.next();
                    char type;
                    if (temp.equals("a")) {
                        type = Moves.MOVE_SLIDE;
                    } else {
                        type = Moves.MOVE_FSLIDE;
                    }
                    temp = parser.next();
                    int tx = 0;
                    int ty = 0;
                    int length = Math.max(rules.getWidth(), rules.getHeight());
                    for (int i = 1; i < length; ++i) {
                        tx += x;
                        ty += y;
                        tmp.addEat(tx, ty, type);
                    }
                }
                temp = parser.next();
                temp = parser.next();
                temp = temp.substring(1, temp.length() - 1);
                if (temp.equals("slide")) {
                    tmp.setEatType(tmp.getEatCount() - 1, '0');
                }
                if (temp.equals("jump")) {
                    tmp.setEatType(tmp.getEatCount() - 1, '1');
                }
                if (temp.equals("fslide")) {
                    tmp.setEatType(tmp.getEatCount() - 1, '2');
                }
                if (temp.equals("fjump")) {
                    tmp.setEatType(tmp.getEatCount() - 1, '3');
                }
                temp = parser.next();
                if (!temp.equals("}")) {
                    return false;
                }
            }
        }
        myTemplate.add(tmp);
        return true;
    }

    private boolean postionFromString(String text, int begin,
            int[] closebraces, Rules rules) {
        Scanner parser = new Scanner(text);
        String temp = "";
        while (parser.hasNext()) {
            temp = parser.next();
            if (temp.equals("black")) {
                temp = parser.next();
                temp = parser.next();
                temp = temp.substring(1, temp.length() - 1);
                String name = temp;
                temp = parser.next();
                temp = parser.next();
                int x = Integer.valueOf(temp).intValue();
                temp = parser.next();
                temp = parser.next();
                int y = Integer.valueOf(temp).intValue();
                int length = myTemplate.size();
                for (int i = 0; i < length; ++i) {
                    if (myTemplate.get(i).getName().equals(name)) {
                        myTemplate.get(i).setX(x);
                        myTemplate.get(i).setY(y);
                        rules.addBlack(myTemplate.get(i));
                        break;
                    }
                }
            }
            if (temp.equals("white")) {
                temp = parser.next();
                temp = parser.next();
                temp = temp.substring(1, temp.length() - 1);
                String name = temp;
                temp = parser.next();
                temp = parser.next();
                int x = Integer.valueOf(temp).intValue();
                temp = parser.next();
                temp = parser.next();
                int y = Integer.valueOf(temp).intValue();
                int length = myTemplate.size();
                for (int i = 0; i < length; ++i) {
                    if (myTemplate.get(i).getName().equals(name)) {
                        myTemplate.get(i).setX(x);
                        myTemplate.get(i).setY(y);
                        rules.addWhite(myTemplate.get(i));
                        break;
                    }
                }
            }
        }
        return true;
    }

    

}
